package controller

import (
	"bluebell/dao/redis"
	"bluebell/logic"
	"bluebell/models"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
	"net/http"
)

// SignUpHandler 请求注册
func SignUpHandler(ctx *gin.Context) {
	// 1.获取参数和参数校验
	var params models.ParamSignUp
	if err := ctx.ShouldBindJSON(&params); err != nil {
		zap.L().Error("SignUp with invalid param", zap.Error(err)) // 记录日志(使用zap日志库方法),Error错误类型

		// 判断是错误是否validator.ValidationErrors类型(错误也可能不是参数错误引起的)
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(ctx, 400, "请求方式有误") // 返回参数校验错误信息
			return
		}
		ResponseError(ctx, 400, removeTapStruct(errs.Translate(trans))) // 翻译错误(Translate: 调用翻译方法, trans: 使用的翻译器)
		return
	}
	// 2.处理注册逻辑
	token, err := logic.SignUp(&params)
	if err != nil {
		zap.L().Error("logic.SignUp failed", zap.Error(err)) // 记录日志(使用zap日志库方法),Error错误类型

		ResponseError(ctx, 400, err.Error())
		return
	}
	// 3.返回成功信息
	ResponseSuccess(ctx, 200, "注册成功", token)
}

// LoginHandler 登录
func LoginHandler(ctx *gin.Context) {
	// 1.获取请求参数及参数校验
	var params models.ParamLogin
	if err := ctx.ShouldBindJSON(&params); err != nil {
		// 记录日志(使用zap日志库方法),Error错误类型
		zap.L().Error("Login with invalid param", zap.Error(err))

		// 判断是错误是否validator.ValidationErrors类型(错误也可能不是翻译引起的)
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(ctx, 400, "传参有误") // 返回参数校验错误信息
			return
		}
		ResponseError(ctx, 400, removeTapStruct(errs.Translate(trans))) // 翻译错误(Translate: 调用翻译方法, trans: 使用的翻译器)
		return
	}
	// 2.处理登录逻辑
	data, err := logic.Login(&params)
	if err != nil {
		zap.L().Error("logic.Login failed", zap.Error(err)) // 记录日志(使用zap日志库方法),Error错误类型

		ResponseError(ctx, 400, err.Error())
		return
	}
	// 3.返回成功信息
	ResponseSuccess(ctx, 200, "登录成功", data)
}

// UserInfoHandler 用户获取信息
func UserInfoHandler(ctx *gin.Context) {
	// 1.获取用户id(token中)
	uid, err := getCurrentUserID(ctx)
	if err != nil {
		ResponseError(ctx, http.StatusForbidden, err.Error())
	}
	// 2.检测是否已缓存(redis)
	data := redis.GetUserInfoInRedis(uid)
	if len(data) != 0 {
		ResponseSuccess(ctx, http.StatusOK, "登录成功", data)
		return
	}
	// 3.处理获取信息逻辑
	userInfo := map[string]string{}
	userInfo, err = logic.GetUserInfo(uid)
	if err != nil {
		zap.L().Error("logic.Login failed", zap.Error(err)) // 记录日志(使用zap日志库方法),Error错误类型

		ResponseError(ctx, http.StatusBadRequest, err.Error())
		return
	}
	// 4.返回成功信息
	ResponseSuccess(ctx, http.StatusOK, "登录成功", userInfo)
}
